# -*- coding: utf-8 -*-
# @Time: 2025/2/6 17:27
# @Author: foxhuty
# @File: get_max_min_data.py

import pandas as pd
import numpy as np


def calculate_grade_info(sorted_data, subject, start_index, num_students) -> tuple:
    """
    计算指定等级的卷面分数区间、人数和最终该等级的数据
    :param sorted_data: 排序后的成绩数据
    :param subject: 学科名称
    :param start_index: 起始索引
    :param num_students: 该等级理论上的学生数量
    :return: 该等级的最高分、最低分、实际人数和最终该等级的数据
    """
    # 初步确定等级数据
    grade_data = sorted_data.loc[start_index:(start_index + num_students - 1), subject]
    grade_max = grade_data.max()
    grade_min = grade_data.min()

    # 再次切片确保最低分的学生都在该等级
    final_grade_data = sorted_data[sorted_data[subject] >= grade_min]
    final_grade_data = final_grade_data[start_index:]  # 截取从 start_index 开始的数据，避免包含前面等级的学生

    # 确定实际等级人数
    grade_count = len(final_grade_data)

    return grade_max, grade_min, grade_count, final_grade_data


def get_subject_max_min_score(data, subject) -> tuple:
    """
    用于计算获取各等级的卷面分区间（Y1-Y2)
    :param data:
    :param subject:
    :return: 各等级的卷面分区间（Y1-Y2)
    """
    max_score = []
    min_score = []
    grade_counts = []
    final_grade_datas = []
    subject_num = data[subject].count()

    # 提前计算各等级人数
    grade_ratios = [0.15, 0.35, 0.35, 0.13]
    grade_nums = [int(subject_num * ratio) for ratio in grade_ratios]

    # 对数据进行一次排序
    sorted_data = data.sort_values(by=subject, ascending=False, ignore_index=True)

    start_index = 0
    grade_names = ['A', 'B', 'C', 'D', 'E']

    # 计算 A、B、C、D 等级
    for i, num in enumerate(grade_nums):
        grade_max, grade_min, grade_count, final_grade_data = calculate_grade_info(sorted_data, subject, start_index,
                                                                                   num)
        max_score.append(grade_max)
        min_score.append(grade_min)
        grade_counts.append(grade_count)
        final_grade_datas.append(final_grade_data)
        start_index += grade_count

    # 计算 E 等级
    remaining_count = subject_num - start_index
    if remaining_count > 0:
        grade_max, grade_min, grade_count, final_grade_data = calculate_grade_info(sorted_data, subject, start_index,
                                                                                   remaining_count)
        max_score.append(grade_max)
        min_score.append(grade_min)
        grade_counts.append(grade_count)
        final_grade_datas.append(final_grade_data)
    else:
        # 如果没有剩余学生，E 等级人数为 0，最高分和最低分设为 NaN
        grade_max = np.nan
        grade_min = np.nan
        grade_count = 0
        final_grade_data = pd.Series()
        max_score.append(grade_max)
        min_score.append(grade_min)
        grade_counts.append(grade_count)
        final_grade_datas.append(final_grade_data)

    # 输出各等级人数和卷面分数区间信息
    for i, grade_name in enumerate(grade_names):
        print(f'{subject}学科{grade_name}等级人数为：{grade_counts[i]}')
    print(
        f'{subject}学科等级卷面Y1的值分别为：{min_score[0]}, {min_score[1]}, {min_score[2]}, {min_score[3]}, {min_score[4]}, '
        f'Y2的值分别为：{max_score[0]}, {max_score[1]}, {max_score[2]}, {max_score[3]}, {max_score[4]}')

    return max_score, min_score


if __name__ == '__main__':

    # ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 总表各学科等级人数及卷面分值区间 ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
    # 政治学科A等级人数为：21, B等级人数为：56, C等级人数为：50, D等级人数为：14, E等级人数为：0
    # 政治学科等级卷面Y1的值分别为：68.0, 52.0, 35.0, 17.0, nan, Y2的值分别为：86.0, 67.0, 51.0, 34.0, nan
    # 地理学科A等级人数为：33, B等级人数为：72, C等级人数为：72, D等级人数为：25, E等级人数为：0
    # 地理学科等级卷面Y1的值分别为：68.0, 51.0, 34.0, 20.0, nan, Y2的值分别为：86.0, 67.0, 50.0, 33.0, nan
    # 化学学科A等级人数为：27, B等级人数为：58, C等级人数为：59, D等级人数为：20, E等级人数为：0
    # 化学学科等级卷面Y1的值分别为：67.0, 54.0, 40.0, 26.0, nan, Y2的值分别为：82.0, 66.0, 53.0, 39.0, nan
    # 生物学科A等级人数为：14, B等级人数为：32, C等级人数为：32, D等级人数为：11, E等级人数为：1
    # 生物学科等级卷面Y1的值分别为：74.0, 64.0, 49.0, 37.0, 24.0, Y2的值分别为：93.0, 73.0, 63.0, 48.0, 24.0
    # ** ** ** ** ** ** ** ** ** ** *高2026级学生10月考成绩汇总.xlsx文件数据处理完成，excel数据表已生成在D:\data_test_files文件夹中 ** ** ** ** ** ** ** ** ** ** *
    file_path = r'D:\data_test_files\成都十一中高2023级半期考试.xlsx'
    data_df = pd.read_excel(file_path, sheet_name='总表')
    print(data_df.head())
    added_columns = [col for col in data_df.columns.tolist() if col in ['政治', '化学', '地理', '生物']]
    print(added_columns)
    for column in added_columns:
        get_subject_max_min_score(data_df, column)
